<template>
	<div class="scroll-better">
		<el-row align="middle">
			<el-col :span="1">
				<el-slider v-model="val" :max="max" vertical :show-tooltip="false" :height="sliderHeight" />
			</el-col>
			<el-col :span="23">
				<ol class="parent" ref="scrollBetter">
					<li v-for="(item, index) in treeData" :class="[item.id, curItem == item.id ? 'active' : '']" :key="index">
						<h4 class="ellipsis" :ref="`${item.id}-scroll-better`">
							<el-tooltip effect="light" :disabled="isShowToolTip">
								<template #content>{{ item.name }}</template>
								<a @mouseover="isToolTip" @click="scrollTo(item.id)" :href="'#' + item.id">{{ item.name }}</a>
							</el-tooltip>
						</h4>
						<div v-if="item.children?.length > 0">
							<ul class="child">
								<li v-for="(itemChild, idenx1) in item.children"
									:class="[itemChild.id, curItem == itemChild.id ? 'active' : '']" :title="itemChild.name" :key="idenx1">
									<h5 class="ellipsis" :ref="`${itemChild.id}-scroll-better`">
										<el-tooltip effect="light" :disabled="isShowToolTip">
											<template #content>{{ itemChild.name }}</template>
											<a @mouseover="isToolTip" @click.stop="scrollTo(itemChild.id)" :href="'#' + itemChild.id">{{ itemChild.name }}</a>
										</el-tooltip>
									</h5>
									<div v-if="itemChild.children?.length > 0">
										<ul class="child">
											<li v-for="(itemChildChild, idenx2) in itemChild.children"
												:class="[itemChildChild.id, curItem == itemChildChild.id ? 'active' : '']"
												:title="itemChildChild.name" :key="idenx2">
												<h5 class="ellipsis" :ref="`${itemChildChild.id}-scroll-better`">
													<el-tooltip effect="light" :disabled="isShowToolTip">
														<template #content>{{ itemChildChild.name }}</template>
														<a @mouseover="isToolTip" @click.stop="scrollTo(itemChildChild.id)"
															:href="'#' + itemChildChild.id">{{ itemChildChild.name }}</a>
													</el-tooltip>
												</h5>
											</li>
										</ul>
									</div>
								</li>
							</ul>
						</div>
					</li>
				</ol>
			</el-col>
		</el-row>
	</div>
</template>
<script setup>
// 父组件参数
const props = defineProps({
	treeData: Array
})
// 组件触发的自定义事件
const emits = defineEmits(['updateScroll']);
// 当前对象实例
const { proxy } = getCurrentInstance();

// 左侧滚动条最大值
const max = ref(100);
// 左侧滚动条当前值
let val = ref(100);
// 左侧滚动条高度
const sliderHeight = ref('0px');

// 列表对象
const scrollBetter = ref();
let curItem = ref('');
// 监听数据变化
watch(() => props.treeData, () => {
	sliderHeight.value = scrollBetter.value.clientHeight + 'px';
}, { deep: true, flush: 'post' })
// 滚动操作
const addActive = (id, children) => {
	curItem.value = id
	if (!children) {
		let item = proxy.$refs[`${id}-scroll-better`]
		if (item) {
			let itemOffsetTop = item[0].offsetTop + item[0].clientHeight / 2
			val.value = 100 - itemOffsetTop / scrollBetter.value.clientHeight * 100
		}
	}
}
// 滚动到指定id
const scrollTo = (id) => {
	// 滚动操作
	addActive(id);
	// 修改id
	emits('updateScroll', id);
}

// 是否禁用ToolTip
const isShowToolTip = ref(true);
// 鼠标悬停提示
const isToolTip = (e) => {
	const selfWidth = e.target.offsetWidth;
	const parentWidth = e.target.parentNode.offsetWidth;
	if (selfWidth > parentWidth) {
		isShowToolTip.value = false;
	} else {
		isShowToolTip.value = true;
	}
}

// 抛出
defineExpose({
	addActive
})
</script>
<style lang="scss">
$baseColor: #107ce5;

.scroll-better {
	position: sticky;
	top: 120px;

	.el-slider {
		width: fit-content;

		.el-slider__bar {
			background-color: transparent;
		}
	}

	.parent {
		position: relative;

		ul {
			list-style: disc;
			padding-left: 1em;
		}

		li {
			width: 100%;
			color: #333;
			font-weight: bold;

			a {
				font-size: 18px;
				font-weight: bold;
			}
		}

		.child {
			li {
				color: #666;

				a {
					font-size: 16px;
					font-weight: bold;
				}
			}

			.active {
				color: $baseColor;
			}
		}

		.active {
			color: $baseColor;
		}
	}

	.ellipsis {
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}
}
</style>